package mongo

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/cgs/app/models"
	"cgs-server/server/cgs/app/models/dto"
	v1 "cgs-server/server/cgs/app/models/v1"
	"cgs-server/server/cgs/app/models/vo"
	"cgs-server/server/cgs/app/store"
	"cgs-server/server/model"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
)

type app struct {
	db             *helper.Mongo
	collectionName string
}

func (a *app) ListConfig(config *dto.Config, user *model.User, opts v1.ListOptions) (*vo.ConfigList, error) {
	filter := opts.GetFilter()
	var res vo.ConfigList
	err := a.db.FindMany(a.ConfigCollectionName(config.VisualType), filter, &res, opts.GetOptions())
	return &res, err
}

func (a *app) Save(app *dto.App, user *model.User, opts v1.CreateOptions) error {
	app.ResolveEntity(app, user)
	_, err := a.db.InsertOne(a.AppCollectionName(), app)
	return err
}

func (a *app) Update(app *dto.App, user *model.User, opts v1.UpdateOptions) error {
	filter := opts.GetFilter()
	if !app.Id.IsZero() {
		filter["ID"] = app.Id
	} else {
		return fmt.Errorf("id is required")
	}
	app.ResolveFilter(app, user, &filter)
	set := bson.M{}
	if app.Title != "" {
		set["Title"] = app.Title
	}
	if app.BackgroundUrl != "" {
		set["BackgroundUrl"] = app.BackgroundUrl
	}
	if app.Theme != nil {
		set["theme"] = app.Theme
	}
	if app.Icon != nil {
		set["icon"] = app.Icon
	}
	if app.Category != nil {
		set["Category"] = app.Category
	}
	if app.OrgCategory != nil {
		set["orgCategory"] = app.OrgCategory
	}
	if app.Password != nil {
		set["Password"] = app.Password
	}
	if app.Status != nil {
		set["Status"] = app.Status
	}
	if app.Status != nil {
		set["Status"] = app.Status
	}
	if app.WorksheetGroupIds != nil {
		set["worksheetGroupIds"] = app.WorksheetGroupIds
	}
	app.ResolveUpdateCondition(app, user, &set)
	update := bson.M{
		"$set": set,
	}
	_, err := a.db.UpdateOne(a.AppCollectionName(), filter, update)
	return err

}

func (a *app) Get(app *models.App, user *model.User, opts v1.GetOptions) (*vo.App, error) {
	filter := bson.M{}
	if !app.Id.IsZero() {
		filter["ID"] = app.Id
	}
	app.ResolveFilter(app, user, &filter)
	result := &vo.App{}
	find, err := a.db.FindOne(a.AppCollectionName(), filter, result)
	if !find {
		return nil, fmt.Errorf("app not found: %s", app.GetId())
	}
	return result, err
}

func (a *app) AppCollectionName(visualType ...string) string {
	if len(visualType) > 0 {
		return a.collectionName + visualType[0]
	}

	return a.collectionName + "App"
}

func (a *app) ConfigCollectionName(visualType ...string) string {
	if len(visualType) > 0 {
		return a.collectionName + visualType[0] + "Config"
	}
	return a.collectionName + "AppConfig"
}

func newAppStore(d *datastore) store.AppStore {
	return &app{
		db:             d.db,
		collectionName: server.CgsPortalVisualCollectionName,
	}
}
